/*
 * DAOConnectionSingleton.java
 *
 * Created on 21 agosto 2006, 16.22
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package it.azienda.framework.persistenza;

import org.hibernate.*;
import org.hibernate.cfg.*;

public class DAOConnectionSingleton {
    
    private static SessionFactory sessionFactory;
    private static final ThreadLocal threadSession = new ThreadLocal();
    private static final ThreadLocal threadTransaction = new ThreadLocal();
    
    public static void init(){
        try {
            Configuration configuration = new Configuration();
            sessionFactory = configuration.configure().buildSessionFactory();
        } catch (Throwable ex) {
            ex.printStackTrace();
            //System.out.println("Eccezione nella costruzione della SessionFactory: " + ex.getMessage());
            throw new ExceptionInInitializerError(ex);
        }
    }
    
    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }
    
    public static Session newSession()  {
        Session s = (Session) getThreadSession().get();
        if (s == null) {
            s = getSessionFactory().openSession();
            getThreadSession().set(s);
            //System.out.println("Session Aperta nel Singleton: "+threadSession.toString());
        }
        return s;
    }
    
    public static void closeSession() {
        Session s = (Session) getThreadSession().get();
        getThreadSession().set(null);
        if (s != null && s.isOpen()) {
            //System.out.println("Session Chiusa nel Singleton: "+threadSession.toString());
            s.close();
            
        }
    }
    
    public static void beginTransaction() throws DAOException {
        Transaction transaction = (Transaction) threadTransaction.get();
        try {
            if (transaction == null) {
                Session session = newSession();
                transaction = session.beginTransaction();
                threadTransaction.set(transaction);
                //System.out.println("Transaction BEGIN nel Singleton: "+transaction.toString());
            }
        } catch (HibernateException ex) {
            throw new DAOException(ex);
        }
    }
    
    public static void commitTransaction() throws DAOException {
        Transaction transaction = (Transaction) threadTransaction.get();
        try {
            if (transaction != null && !transaction.wasCommitted() && !transaction.wasRolledBack() ) {
                transaction.commit();
                //System.out.println("Transaction COMMITT nel Singleton: "+transaction.toString());
            }
            threadTransaction.set(null);
        } catch (HibernateException ex) {
            rollbackTransaction();
            throw new DAOException(ex);
        }
    }
    
    public static void rollbackTransaction() throws DAOException {
        Transaction transaction = (Transaction) threadTransaction.get();
        try {
            threadTransaction.set(null);
            if (transaction != null && !transaction.wasCommitted() && !transaction.wasRolledBack() ) {
                transaction.rollback();
            }
        } catch (HibernateException ex) {
            throw new DAOException(ex);
        } finally {
            closeSession();
        }
    }

    public static ThreadLocal getThreadSession() {
        return threadSession;
    }    
}